import requests
from calc_manager.base.plugins import PluginObject
import hashlib
from pyNastran.op2.op2 import read_op2
# read op2 result file
class OP2Reader(PluginObject):

    def __init__(self, oss_url, local_path = None) -> None:
        print(f"OP2Reader init start")
        if local_path:
            file_path = local_path
            print(f"OP2Reader init use local path: {file_path}")
        else:
            response = requests.get(oss_url)
            response.raise_for_status()  # 确保请求成功

            file_hash = hashlib.md5(response.content).hexdigest()
            file_path = f"/tmp/{file_hash}.op2"

            with open(file_path, "wb") as f:
                f.write(response.content)
            print(f"Downloaded OP2 file from {oss_url} and saved to {file_path}")

        print(f"OP2Reader init start read_op2")
        import time
        start_time = time.time()
        self.reader = read_op2(file_path, build_dataframe=False)
        end_time = time.time()
        print(f"OP2Reader init done, took {end_time - start_time:.2f} seconds")

    # 商软肯需要实现的功能,通过给定单元编号和其余数据来获取需要的应力值/应变值
    def get_shell_element_stress_by_id(
        self, eid, bdf_model, position=0, component="von_mises", subcase_id=1
    ):
        # 根据单元id查找单元的应力值,目前demo场景 subcase_id=1 应力类型为von-mises
        # position 0代表Top  1代表Bottom

        # 根据单元编号etype获取单元形状etype eg. cquad4/ctria3
        etype = bdf_model.get_element_fields_by_id(eid)["element_type"]

        if etype == "CQUAD4":
            data = self.reader.get_result("stress.cquad4_stress")[subcase_id]
        elif etype == "CTRIA3":
            data = self.reader.get_result("stress.ctria3_stress")[subcase_id]

        # element_node可获取结果行数对应的element_id
        element_node = data.element_node
        # 获取所有cquad4单元的应力结果表
        df = data.data_frame
        # 根据入参定位结果所在的行数//2
        for index, item in enumerate(element_node):
            if item[0] == eid:
                # single_mises_data = df[component].iloc[index // 2]
                if position:
                    return df[component].iloc[index + 1]
                else:
                    return df[component].iloc[index]

    def get_subcase_id(self):
        return list(self.reader.subcase_key.keys())[0]

    def get_result_from_comp_and_subcase(self, comp, subcase_id):
        return self.reader.get_result(comp)[subcase_id]